package com.paradox.dynamicdatasourcespringbootstarter.autoConfig;

import com.paradox.dynamicdatasourcespringbootstarter.aop.DynamicDatasourceAop;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.*;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Configuration(proxyBeanMethods = false)
@ComponentScan(basePackageClasses=DynamicDatasourceAop.class)
@ConditionalOnProperty("paradox.datasource")
//@AutoConfigureBefore(DataSourceAutoConfiguration.class)
public class DynamicDatasourceAutoConfiguration {

    public static final ThreadLocal<String> LOOKUP_KEY = new ThreadLocal<String>();

    public static final String READ="read";
    public static final String WRITE="write";

    public static void resetLookupKey(){
        LOOKUP_KEY.remove();
        log.info("重置数据源！");
    }
    public static void setLookupKey(String key){
        LOOKUP_KEY.set(key);
        log.info("切换数据源-->"+key+"!");
    }

    @Bean("readDataSource")
    @ConfigurationProperties("paradox.datasource.read")
    DataSource readDataSource(DataSourceProperties properties) {
        DataSource dataSource = (HikariDataSource) DataSourceBuilder.create().build();
        //HikariDataSource dataSource = createDataSource(mainProperties, HikariDataSource.class);
        /*if (StringUtils.hasText(mainProperties.getName())) {
            dataSource.setPoolName(mainProperties.getName());
        }*/
        return dataSource;
    }

    @Bean("writeDataSource")
    @ConfigurationProperties("paradox.datasource.write")
    DataSource writeDataSource(DataSourceProperties properties) {
        DataSource dataSource = (HikariDataSource) DataSourceBuilder.create().build();
        //HikariDataSource dataSource = createDataSource(bakProperties, HikariDataSource.class);
        /*if (StringUtils.hasText(bakProperties.getName())) {
            dataSource.setPoolName(bakProperties.getName());
        }*/
        return dataSource;
    }

    @Primary
    @Bean
    @DependsOn({ "readDataSource", "writeDataSource"})
    DataSource dataSource(DataSource readDataSource,DataSource writeDataSource){
        AbstractRoutingDataSource dataSource=new AbstractRoutingDataSource() {
            @Override
            protected Object determineCurrentLookupKey() {
                return LOOKUP_KEY.get();
            }
        };
        dataSource.setDefaultTargetDataSource(readDataSource);
        Map<Object,Object> targetDataSources=new HashMap<Object,Object>();
        targetDataSources.put("read",readDataSource);
        targetDataSources.put("write",writeDataSource);
        dataSource.setTargetDataSources(targetDataSources);
        return dataSource;
    }
}
